package com.itheima.web.manager;

import cn.hutool.captcha.LineCaptcha;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import com.alibaba.fastjson.JSON;
import com.itheima.domain.db.Admin;
import com.itheima.domain.vo.AnalysisSummaryVo;
import com.itheima.service.db.AdminService;
import com.itheima.service.db.AnalysisService;
import com.itheima.util.ConstantUtil;
import com.itheima.util.JwtUtil;
import com.itheima.web.exception.BusinessException;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Component
public class AdminManager {

    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    //生成验证码
    public LineCaptcha verification(String uuid) {
        //1.产生验证码对象
        LineCaptcha lineCaptcha = new LineCaptcha(200, 100);

        String code = lineCaptcha.getCode();

        System.out.println("验证码为:" + code);
        //2.存入到redis   单位一定别写错了   MINUTES 分钟
        stringRedisTemplate.opsForValue().set(ConstantUtil.ADMIN_CODE+uuid, code , 5 , TimeUnit.MINUTES);
        return lineCaptcha;
    }

    @DubboReference
    private AdminService adminService;
    /**
     * 1.获得redis的验证码
     * 2.比较验证码
     * 3.根据用户名查询用户对象
     * 4.比较密码
     * 5.制作token
     * 6.操作缓存
     * 7.构建返回值
     */
    //用户登录
    public ResponseEntity login(String username, String password, String verificationCode, String uuid) {
        //1.获得redis的验证码
        String redisCode = stringRedisTemplate.opsForValue().get(ConstantUtil.ADMIN_CODE + uuid);
        //2.比较验证码
        if(!StrUtil.equals(redisCode  , verificationCode )){
            //自己抛出自己想要的异常
            throw new BusinessException("验证码错误");
        }
        //3.根据用户名查询用户对象
        Admin admin = adminService.findByUsernameAndPassword(username);
        if(admin == null){
            throw new BusinessException("用户名输入错误");
        }
        //4.比较密码
        String md5Pwd = SecureUtil.md5(password);
        if(!StrUtil.equals( md5Pwd , admin.getPassword() )){
            throw new BusinessException("密码输入错误");
        }
        //5.制作token-不允许传入密码
        admin.setPassword( null );//设置密码为空
        //将对象转换成map
        Map<String, Object> map = BeanUtil.beanToMap(admin);
        String token = JwtUtil.createToken(map);

        //制作一个json
        String json = JSON.toJSONString(admin);

        //6.操作缓存 将登录数据放入缓存 30分钟
        stringRedisTemplate.opsForValue().set(ConstantUtil.ADMIN_TOKEN  + token,json , 30 , TimeUnit.MINUTES );
        //7.构建返回值
        Map returnMap = new HashMap();
        returnMap.put("token" , token);
        stringRedisTemplate.delete(ConstantUtil.ADMIN_CODE + uuid);
        return ResponseEntity.ok(returnMap);
    }

    //获得用户的基本信息
    public Admin profile(String token) {
        //坑 前端默认token之前自动加一个 Bearer空格 这么一个字符串
        token = token.replaceAll("Bearer ","");
        //获得json数据
        String json = stringRedisTemplate.opsForValue().get(ConstantUtil.ADMIN_TOKEN + token);

        if(json==null){
            throw new BusinessException("请刷新登录页面.重新登录");
        }
        //转换成admin
        Admin admin = JSON.parseObject(json, Admin.class);

        //续期操作
        stringRedisTemplate.opsForValue().set(ConstantUtil.ADMIN_TOKEN  + token,json , 30 , TimeUnit.MINUTES );
        return admin;
    }

    //登出
    public ResponseEntity logout(String token) {
        //坑 前端默认token之前自动加一个 Bearer空格 这么一个字符串
        token = token.replaceAll("Bearer ","");
        //删除token
        stringRedisTemplate.delete(ConstantUtil.ADMIN_TOKEN  + token);
        return ResponseEntity.ok(null);
    }


    @DubboReference
    private AnalysisService analysisService;
    //概要统计
    public ResponseEntity summary() {
        AnalysisSummaryVo vo = analysisService.findAnalysisSummaryVo();
        return ResponseEntity.ok(vo);
    }
}
